<html><!-- Created using the cpp_pretty_printer from the dlib C++ library.  See http://dlib.net for updates. --><head><title>dlib C++ Library - sockets_kernel_2.cpp</title></head><body bgcolor='white'><pre>
<font color='#009900'>// Copyright (C) 2003  Davis E. King (davis@dlib.net), Miguel Grinberg
</font><font color='#009900'>// License: Boost Software License   See LICENSE.txt for the full license.
</font><font color='#0000FF'>#ifndef</font> DLIB_SOCKETS_KERNEL_2_CPp_
<font color='#0000FF'>#define</font> DLIB_SOCKETS_KERNEL_2_CPp_

<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../platform.h.html'>../platform.h</a>"

<font color='#0000FF'>#ifdef</font> POSIX


<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='sockets_kernel_2.h.html'>sockets_kernel_2.h</a>"
<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>fcntl.h<font color='#5555FF'>&gt;</font>
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../set.h.html'>../set.h</a>"
<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>netinet<font color='#5555FF'>/</font>tcp.h<font color='#5555FF'>&gt;</font>



<font color='#0000FF'>namespace</font> dlib
<b>{</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'>#ifdef</font> HPUX
    <font color='#0000FF'>typedef</font> <font color='#0000FF'><u>int</u></font> dsocklen_t;
<font color='#0000FF'>#else</font>
    <font color='#0000FF'>typedef</font> socklen_t dsocklen_t;
<font color='#0000FF'>#endif</font>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// stuff to ensure that the signal SIGPIPE is ignored before any connections are made
</font><font color='#009900'>// so that when a connection object is shutdown the program won't end on a broken pipe
</font>
    <font color='#0000FF'>namespace</font> sockets_kernel_2_mutex
    <b>{</b>
        mutex startup_lock;
    <b>}</b>


    <font color='#0000FF'><u>void</u></font> <b><a name='sockets_startup'></a>sockets_startup</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#009900'>// mutex crap to make this function thread safe
</font>        sockets_kernel_2_mutex::startup_lock.<font color='#BB00BB'>lock</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>static</font> <font color='#0000FF'><u>bool</u></font> init <font color='#5555FF'>=</font> <font color='#979000'>false</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>init <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>false</font><font face='Lucida Console'>)</font>
        <b>{</b>
            init <font color='#5555FF'>=</font> <font color='#979000'>true</font>;
            <font color='#BB00BB'>signal</font><font face='Lucida Console'>(</font> SIGPIPE, SIG_IGN<font face='Lucida Console'>)</font>;
        <b>}</b>
        sockets_kernel_2_mutex::startup_lock.<font color='#BB00BB'>unlock</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
    <b>}</b>


<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#009900'>// lookup functions
</font>
    <font color='#0000FF'><u>int</u></font>
    <b><a name='get_local_hostname'></a>get_local_hostname</b> <font face='Lucida Console'>(</font>
        std::string<font color='#5555FF'>&amp;</font> hostname
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>try</font> 
        <b>{</b>
            <font color='#0000FF'><u>char</u></font> temp[MAXHOSTNAMELEN];

            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>gethostname</font><font face='Lucida Console'>(</font>temp,MAXHOSTNAMELEN<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            <font color='#009900'>// ensure that NUL is at the end of the string
</font>            temp[MAXHOSTNAMELEN<font color='#5555FF'>-</font><font color='#979000'>1</font>] <font color='#5555FF'>=</font> '<font color='#FF0000'>\0</font>';

            hostname <font color='#5555FF'>=</font> temp; 
        <b>}</b>
        <font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>

        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>

<font color='#009900'>// -----------------
</font>
<font color='#009900'>// cygwin currently doesn't support the getaddrinfo stuff
</font><font color='#0000FF'>#ifndef</font> __CYGWIN__

    <font color='#0000FF'><u>int</u></font> 
    <b><a name='hostname_to_ip'></a>hostname_to_ip</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> hostname,
        std::string<font color='#5555FF'>&amp;</font> ip,
        <font color='#0000FF'><u>int</u></font> n
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>try</font> 
        <b>{</b>
            set<font color='#5555FF'>&lt;</font>std::string<font color='#5555FF'>&gt;</font>::kernel_1a sos;

            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>hostname.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;

            addrinfo<font color='#5555FF'>*</font> result <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>getaddrinfo</font><font face='Lucida Console'>(</font>hostname.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,<font color='#979000'>0</font>,<font color='#979000'>0</font>,<font color='#5555FF'>&amp;</font>result<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            addrinfo<font color='#5555FF'>*</font> result_orig <font color='#5555FF'>=</font> result;

            <font color='#009900'>// loop over all the addrinfo structures and add them to the set.  the reason for doing
</font>            <font color='#009900'>// this dumb crap is because different platforms return all kinds of weird garbage.  many
</font>            <font color='#009900'>// return the same ip multiple times, etc.
</font>            <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>result <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'><u>char</u></font> temp[<font color='#979000'>16</font>];
                <font color='#BB00BB'>inet_ntop</font> <font face='Lucida Console'>(</font>
                    AF_INET,
                    <font color='#5555FF'>&amp;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font><font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr_in<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>result<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>ai_addr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>sin_addr<font face='Lucida Console'>)</font>,
                    temp,<font color='#979000'>16</font>
                    <font face='Lucida Console'>)</font>;

                result <font color='#5555FF'>=</font> result<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>ai_next;

                ip.<font color='#BB00BB'>assign</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sos.<font color='#BB00BB'>is_member</font><font face='Lucida Console'>(</font>ip<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>false</font><font face='Lucida Console'>)</font>
                    sos.<font color='#BB00BB'>add</font><font face='Lucida Console'>(</font>ip<font face='Lucida Console'>)</font>;
            <b>}</b>

            <font color='#BB00BB'>freeaddrinfo</font><font face='Lucida Console'>(</font>result_orig<font face='Lucida Console'>)</font>;

            <font color='#009900'>// now return the nth unique ip address
</font>            <font color='#0000FF'><u>int</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>sos.<font color='#BB00BB'>move_next</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>i <font color='#5555FF'>=</font><font color='#5555FF'>=</font> n<font face='Lucida Console'>)</font>
                <b>{</b>
                    ip <font color='#5555FF'>=</font> sos.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
                    <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
                <b>}</b>
                <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i;
            <b>}</b>

            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>
        <font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>
        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>


<font color='#009900'>// -----------------
</font>
    <font color='#0000FF'><u>int</u></font>
    <b><a name='ip_to_hostname'></a>ip_to_hostname</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> ip,
        std::string<font color='#5555FF'>&amp;</font> hostname
    <font face='Lucida Console'>)</font>
    <b>{</b>

        <font color='#0000FF'>try</font> 
        <b>{</b>

            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>ip.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;

            sockaddr_in sa;
            sa.sin_family <font color='#5555FF'>=</font> AF_INET;
            <font color='#BB00BB'>inet_pton</font><font face='Lucida Console'>(</font>AF_INET,ip.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,<font color='#5555FF'>&amp;</font>sa.sin_addr<font face='Lucida Console'>)</font>;

            <font color='#0000FF'><u>char</u></font> temp[NI_MAXHOST];
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>getnameinfo</font> <font face='Lucida Console'>(</font>
                    <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>sa<font face='Lucida Console'>)</font>,<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>,
                    temp,
                    NI_MAXHOST,
                    <font color='#979000'>0</font>,
                    <font color='#979000'>0</font>,
                    NI_NAMEREQD
                <font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
     
            hostname.<font color='#BB00BB'>assign</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font>;

        <b>}</b>
        <font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>
        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>
<font color='#0000FF'>#else</font>
    <font color='#0000FF'><u>int</u></font> 
    <b><a name='hostname_to_ip'></a>hostname_to_ip</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> hostname,
        std::string<font color='#5555FF'>&amp;</font> ip,
        <font color='#0000FF'><u>int</u></font> n
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>try</font> 
        <b>{</b>
            <font color='#009900'>// lock this mutex since gethostbyname isn't really thread safe
</font>            auto_mutex <font color='#BB00BB'>M</font><font face='Lucida Console'>(</font>sockets_kernel_2_mutex::startup_lock<font face='Lucida Console'>)</font>;

            <font color='#009900'>// if no hostname was given then return error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> hostname.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;

            hostent<font color='#5555FF'>*</font> address;
            address <font color='#5555FF'>=</font> <font color='#BB00BB'>gethostbyname</font><font face='Lucida Console'>(</font>hostname.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>address <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>

            <font color='#009900'>// find the nth address
</font>            in_addr<font color='#5555FF'>*</font> addr <font color='#5555FF'>=</font> <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>in_addr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>address<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>h_addr_list[<font color='#979000'>0</font>]<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>int</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>1</font>; i <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> n; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                addr <font color='#5555FF'>=</font> <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>in_addr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>address<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>h_addr_list[i]<font face='Lucida Console'>)</font>;

                <font color='#009900'>// if there is no nth address then return error
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>addr <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                    <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>

            <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> resolved_ip <font color='#5555FF'>=</font> <font color='#BB00BB'>inet_ntoa</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>addr<font face='Lucida Console'>)</font>;

            <font color='#009900'>// check if inet_ntoa returned an error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>resolved_ip <font color='#5555FF'>=</font><font color='#5555FF'>=</font> NULL<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>

            ip.<font color='#BB00BB'>assign</font><font face='Lucida Console'>(</font>resolved_ip<font face='Lucida Console'>)</font>;

        <b>}</b>
        <font color='#0000FF'>catch</font><font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>

        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>

<font color='#009900'>// -----------------
</font>
    <font color='#0000FF'><u>int</u></font>
    <b><a name='ip_to_hostname'></a>ip_to_hostname</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> ip,
        std::string<font color='#5555FF'>&amp;</font> hostname
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>try</font> 
        <b>{</b>
            <font color='#009900'>// lock this mutex since gethostbyaddr isn't really thread safe
</font>            auto_mutex <font color='#BB00BB'>M</font><font face='Lucida Console'>(</font>sockets_kernel_2_mutex::startup_lock<font face='Lucida Console'>)</font>;

            <font color='#009900'>// if no ip was given then return error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>ip.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;

            hostent<font color='#5555FF'>*</font> address;
            <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> ipnum <font color='#5555FF'>=</font> <font color='#BB00BB'>inet_addr</font><font face='Lucida Console'>(</font>ip.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            <font color='#009900'>// if inet_addr couldn't convert ip then return an error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>ipnum <font color='#5555FF'>=</font><font color='#5555FF'>=</font> INADDR_NONE<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            address <font color='#5555FF'>=</font> <font color='#BB00BB'>gethostbyaddr</font><font face='Lucida Console'>(</font><font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>ipnum<font face='Lucida Console'>)</font>,<font color='#979000'>4</font>,AF_INET<font face='Lucida Console'>)</font>;

            <font color='#009900'>// check if gethostbyaddr returned an error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>address <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            hostname.<font color='#BB00BB'>assign</font><font face='Lucida Console'>(</font>address<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>h_name<font face='Lucida Console'>)</font>;

        <b>}</b>
        <font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>
        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;

    <b>}</b>

<font color='#0000FF'>#endif</font> <font color='#009900'>// __CYGWIN__
</font>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    connection::
    <b><a name='connection'></a>connection</b><font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>int</u></font> sock,
        <font color='#0000FF'><u>int</u></font> foreign_port, 
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> foreign_ip, 
        <font color='#0000FF'><u>int</u></font> local_port,
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> local_ip
    <font face='Lucida Console'>)</font> :
        connection_socket<font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>,
        connection_foreign_port<font face='Lucida Console'>(</font>foreign_port<font face='Lucida Console'>)</font>,
        connection_foreign_ip<font face='Lucida Console'>(</font>foreign_ip<font face='Lucida Console'>)</font>,
        connection_local_port<font face='Lucida Console'>(</font>local_port<font face='Lucida Console'>)</font>,
        connection_local_ip<font face='Lucida Console'>(</font>local_ip<font face='Lucida Console'>)</font>,
        sd<font face='Lucida Console'>(</font><font color='#979000'>false</font><font face='Lucida Console'>)</font>,
        sdo<font face='Lucida Console'>(</font><font color='#979000'>false</font><font face='Lucida Console'>)</font>,
        sdr<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>
    <b>{</b><b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>int</u></font> connection::
    <b><a name='disable_nagle'></a>disable_nagle</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'><u>int</u></font> flag <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'>if</font><font face='Lucida Console'>(</font><font color='#BB00BB'>setsockopt</font><font face='Lucida Console'>(</font> connection_socket, IPPROTO_TCP, TCP_NODELAY, <font face='Lucida Console'>(</font><font color='#0000FF'><u>char</u></font> <font color='#5555FF'>*</font><font face='Lucida Console'>)</font><font color='#5555FF'>&amp;</font>flag, <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>flag<font face='Lucida Console'>)</font> <font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>

        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>long</u></font> connection::
    <b><a name='write'></a>write</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> buf, 
        <font color='#0000FF'><u>long</u></font> num
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> old_num <font color='#5555FF'>=</font> num;
        <font color='#0000FF'><u>long</u></font> status;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> max_send_length <font color='#5555FF'>=</font> <font color='#979000'>1024</font><font color='#5555FF'>*</font><font color='#979000'>1024</font><font color='#5555FF'>*</font><font color='#979000'>100</font>;
        <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>num <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// Make sure to cap the max value num can take on so that if it is 
</font>            <font color='#009900'>// really large (it might be big on 64bit platforms) so that the OS
</font>            <font color='#009900'>// can't possibly get upset about it being large.
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> length <font color='#5555FF'>=</font> std::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font>max_send_length, num<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>send</font><font face='Lucida Console'>(</font>connection_socket,buf,length,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#009900'>// if send was interupted by a signal then restart it
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>continue</font>;
                <b>}</b>
                <font color='#0000FF'>else</font>
                <b>{</b>
                    <font color='#009900'>// check if shutdown or shutdown_outgoing have been called
</font>                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>sdo_called</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                        <font color='#0000FF'>return</font> SHUTDOWN;
                    <font color='#0000FF'>else</font>
                        <font color='#0000FF'>return</font> OTHER_ERROR;
                <b>}</b>
            <b>}</b>
            num <font color='#5555FF'>-</font><font color='#5555FF'>=</font> status;
            buf <font color='#5555FF'>+</font><font color='#5555FF'>=</font> status;
        <b>}</b> 
        <font color='#0000FF'>return</font> old_num;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>long</u></font> connection::
    <b><a name='read'></a>read</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> buf, 
        <font color='#0000FF'><u>long</u></font> num
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'><u>long</u></font> status;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> max_recv_length <font color='#5555FF'>=</font> <font color='#979000'>1024</font><font color='#5555FF'>*</font><font color='#979000'>1024</font><font color='#5555FF'>*</font><font color='#979000'>100</font>;
        <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// Make sure to cap the max value num can take on so that if it is 
</font>            <font color='#009900'>// really large (it might be big on 64bit platforms) so that the OS
</font>            <font color='#009900'>// can't possibly get upset about it being large.
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> length <font color='#5555FF'>=</font> std::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font>max_recv_length, num<font face='Lucida Console'>)</font>;
            status <font color='#5555FF'>=</font> <font color='#BB00BB'>recv</font><font face='Lucida Console'>(</font>connection_socket,buf,length,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#009900'>// if recv was interupted then try again
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                    <font color='#0000FF'>continue</font>;
                <font color='#0000FF'>else</font>
                <b>{</b>
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>sd_called</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                        <font color='#0000FF'>return</font> SHUTDOWN;
                    <font color='#0000FF'>else</font>
                        <font color='#0000FF'>return</font> OTHER_ERROR;
                <b>}</b>
            <b>}</b>
            <font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> <font color='#BB00BB'>sd_called</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> SHUTDOWN;
            <b>}</b>

            <font color='#0000FF'>return</font> status;
        <b>}</b> <font color='#009900'>// while (true)
</font>    <b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>long</u></font> connection::
    <b><a name='read'></a>read</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> buf, 
        <font color='#0000FF'><u>long</u></font> num,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> timeout
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'><u>long</u></font> status;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> max_recv_length <font color='#5555FF'>=</font> <font color='#979000'>1024</font><font color='#5555FF'>*</font><font color='#979000'>1024</font><font color='#5555FF'>*</font><font color='#979000'>100</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>readable</font><font face='Lucida Console'>(</font>timeout<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>false</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> TIMEOUT;

        <font color='#009900'>// Make sure to cap the max value num can take on so that if it is 
</font>        <font color='#009900'>// really large (it might be big on 64bit platforms) so that the OS
</font>        <font color='#009900'>// can't possibly get upset about it being large.
</font>        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> length <font color='#5555FF'>=</font> std::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font>max_recv_length, num<font face='Lucida Console'>)</font>;
        status <font color='#5555FF'>=</font> <font color='#BB00BB'>recv</font><font face='Lucida Console'>(</font>connection_socket,buf,length,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// if recv was interupted then call this a timeout 
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>return</font> TIMEOUT;
            <b>}</b>
            <font color='#0000FF'>else</font>
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>sd_called</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                    <font color='#0000FF'>return</font> SHUTDOWN;
                <font color='#0000FF'>else</font>
                    <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
        <b>}</b>
        <font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> <font color='#BB00BB'>sd_called</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> SHUTDOWN;
        <b>}</b>

        <font color='#0000FF'>return</font> status;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>bool</u></font> connection::
    <b><a name='readable'></a>readable</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> timeout
    <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
    <b>{</b>
        fd_set read_set;
        <font color='#009900'>// initialize read_set
</font>        <font color='#BB00BB'>FD_ZERO</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>read_set<font face='Lucida Console'>)</font>;

        <font color='#009900'>// add the listening socket to read_set
</font>        <font color='#BB00BB'>FD_SET</font><font face='Lucida Console'>(</font>connection_socket, <font color='#5555FF'>&amp;</font>read_set<font face='Lucida Console'>)</font>;

        <font color='#009900'>// setup a timeval structure
</font>        timeval time_to_wait;
        time_to_wait.tv_sec <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>timeout<font color='#5555FF'>/</font><font color='#979000'>1000</font><font face='Lucida Console'>)</font>;
        time_to_wait.tv_usec <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>timeout<font color='#5555FF'>%</font><font color='#979000'>1000</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#979000'>1000</font><font face='Lucida Console'>)</font>;

        <font color='#009900'>// wait on select
</font>        <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> <font color='#BB00BB'>select</font><font face='Lucida Console'>(</font>connection_socket<font color='#5555FF'>+</font><font color='#979000'>1</font>,<font color='#5555FF'>&amp;</font>read_set,<font color='#979000'>0</font>,<font color='#979000'>0</font>,<font color='#5555FF'>&amp;</font>time_to_wait<font face='Lucida Console'>)</font>;

        <font color='#009900'>// if select timed out or there was an error
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> <font color='#979000'>false</font>;
        
        <font color='#009900'>// socket is ready to be read
</font>        <font color='#0000FF'>return</font> <font color='#979000'>true</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    connection::
    ~<b><a name='connection'></a>connection</b> <font face='Lucida Console'>(</font>
    <font face='Lucida Console'>)</font>        
    <b>{</b>
        <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>close</font><font face='Lucida Console'>(</font>connection_socket<font face='Lucida Console'>)</font>;  
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                <font color='#0000FF'>continue</font>;
            <font color='#0000FF'>break</font>;
        <b>}</b>
    <b>}</b>


<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>    <font color='#009900'>// listener object
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    listener::
    <b><a name='listener'></a>listener</b><font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>int</u></font> sock,
        <font color='#0000FF'><u>int</u></font> port,
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> ip
    <font face='Lucida Console'>)</font> :
        listening_socket<font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>,
        listening_port<font face='Lucida Console'>(</font>port<font face='Lucida Console'>)</font>,
        listening_ip<font face='Lucida Console'>(</font>ip<font face='Lucida Console'>)</font>,
        inaddr_any<font face='Lucida Console'>(</font>listening_ip.empty<font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
    <b>{</b><b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    listener::
    ~<b><a name='listener'></a>listener</b> <font face='Lucida Console'>(</font>
    <font face='Lucida Console'>)</font>        
    <b>{</b>
        <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>close</font><font face='Lucida Console'>(</font>listening_socket<font face='Lucida Console'>)</font>;  
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                <font color='#0000FF'>continue</font>;
            <font color='#0000FF'>break</font>;
        <b>}</b>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>int</u></font> listener::
    <b><a name='accept'></a>accept</b> <font face='Lucida Console'>(</font>
        scoped_ptr<font color='#5555FF'>&lt;</font>connection<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> new_connection,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> timeout
    <font face='Lucida Console'>)</font>
    <b>{</b>
        new_connection.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>;
        connection<font color='#5555FF'>*</font> con;
        <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> <font color='#0000FF'>this</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>accept</font><font face='Lucida Console'>(</font>con, timeout<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            new_connection.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font>con<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>return</font> status;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>int</u></font> listener::
    <b><a name='accept'></a>accept</b> <font face='Lucida Console'>(</font>
        connection<font color='#5555FF'>*</font><font color='#5555FF'>&amp;</font> new_connection,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> timeout
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'><u>int</u></font> incoming;
        sockaddr_in incomingAddr;
        dsocklen_t length <font color='#5555FF'>=</font> <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>;

        <font color='#009900'>// implement timeout with select if timeout is &gt; 0
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>timeout <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
        <b>{</b>

            fd_set read_set;
            <font color='#009900'>// initialize read_set
</font>            <font color='#BB00BB'>FD_ZERO</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>read_set<font face='Lucida Console'>)</font>;

            <font color='#009900'>// add the listening socket to read_set
</font>            <font color='#BB00BB'>FD_SET</font><font face='Lucida Console'>(</font>listening_socket, <font color='#5555FF'>&amp;</font>read_set<font face='Lucida Console'>)</font>;

            timeval time_to_wait;


            <font color='#009900'>// loop on select so if its interupted then we can start it again
</font>            <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
            <b>{</b>

                <font color='#009900'>// setup a timeval structure
</font>                time_to_wait.tv_sec <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>timeout<font color='#5555FF'>/</font><font color='#979000'>1000</font><font face='Lucida Console'>)</font>;
                time_to_wait.tv_usec <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>timeout<font color='#5555FF'>%</font><font color='#979000'>1000</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#979000'>1000</font><font face='Lucida Console'>)</font>;

                <font color='#009900'>// wait on select
</font>                <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> <font color='#BB00BB'>select</font><font face='Lucida Console'>(</font>listening_socket<font color='#5555FF'>+</font><font color='#979000'>1</font>,<font color='#5555FF'>&amp;</font>read_set,<font color='#979000'>0</font>,<font color='#979000'>0</font>,<font color='#5555FF'>&amp;</font>time_to_wait<font face='Lucida Console'>)</font>;

                <font color='#009900'>// if select timed out
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                    <font color='#0000FF'>return</font> TIMEOUT;
                
                <font color='#009900'>// if select returned an error
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#009900'>// if select was interupted or the connection was aborted
</font>                    <font color='#009900'>// then go back to select
</font>                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> ECONNABORTED <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
<font color='#0000FF'>#ifdef</font> EPROTO
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EPROTO <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
<font color='#0000FF'>#endif</font>
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> ECONNRESET
                        <font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#0000FF'>continue</font>;
                    <b>}</b>
                    <font color='#0000FF'>else</font>
                    <b>{</b>
                        <font color='#0000FF'>return</font> OTHER_ERROR;
                    <b>}</b>
                <b>}</b>

                <font color='#009900'>// accept the new connection
</font>                incoming<font color='#5555FF'>=</font>::<font color='#BB00BB'>accept</font> <font face='Lucida Console'>(</font>
                    listening_socket,
                    <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>incomingAddr<font face='Lucida Console'>)</font>,
                    <font color='#5555FF'>&amp;</font>length
                    <font face='Lucida Console'>)</font>;

                <font color='#009900'>// if there was an error return OTHER_ERROR
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> incoming <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#009900'>// if accept was interupted then go back to accept
</font>                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> ECONNABORTED <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
<font color='#0000FF'>#ifdef</font> EPROTO
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EPROTO <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
<font color='#0000FF'>#endif</font>
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> ECONNRESET
                        <font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#0000FF'>continue</font>;
                    <b>}</b>
                    <font color='#0000FF'>else</font>
                    <b>{</b>
                        <font color='#0000FF'>return</font> OTHER_ERROR;
                    <b>}</b>
                <b>}</b>

                <font color='#009900'>// if there were no errors then quit loop
</font>                <font color='#0000FF'>break</font>;

            <b>}</b>

        <b>}</b>
        <font color='#009900'>// else if there is no time out then just go into accept
</font>        <font color='#0000FF'>else</font>
        <b>{</b>
            <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#009900'>// call accept to get a new connection
</font>                incoming<font color='#5555FF'>=</font>::<font color='#BB00BB'>accept</font> <font face='Lucida Console'>(</font>
                    listening_socket,
                    <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>incomingAddr<font face='Lucida Console'>)</font>,
                    <font color='#5555FF'>&amp;</font>length
                    <font face='Lucida Console'>)</font>;

                <font color='#009900'>// if there was an error return OTHER_ERROR
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> incoming <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#009900'>// if accept was interupted then go back to accept
</font>                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> ECONNABORTED <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
<font color='#0000FF'>#ifdef</font> EPROTO
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EPROTO <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
<font color='#0000FF'>#endif</font>
                        errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> ECONNRESET
                        <font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#0000FF'>continue</font>;
                    <b>}</b>
                    <font color='#0000FF'>else</font>
                    <b>{</b>
                        <font color='#0000FF'>return</font> OTHER_ERROR;
                    <b>}</b>
                <b>}</b>
                <font color='#0000FF'>break</font>;
            <b>}</b>

        <b>}</b>

        
        <font color='#009900'>// get the port of the foreign host into foreign_port
</font>        <font color='#0000FF'><u>int</u></font> foreign_port <font color='#5555FF'>=</font> <font color='#BB00BB'>ntohs</font><font face='Lucida Console'>(</font>incomingAddr.sin_port<font face='Lucida Console'>)</font>;

        <font color='#009900'>// get the IP of the foreign host into foreign_ip
</font>        <font color='#0000FF'><u>char</u></font> foreign_ip[<font color='#979000'>16</font>];
        <font color='#BB00BB'>inet_ntop</font><font face='Lucida Console'>(</font>AF_INET,<font color='#5555FF'>&amp;</font>incomingAddr.sin_addr,foreign_ip,<font color='#979000'>16</font><font face='Lucida Console'>)</font>;



        <font color='#009900'>// get the local ip for this connection into local_ip
</font>        <font color='#0000FF'><u>char</u></font> temp_local_ip[<font color='#979000'>16</font>];
        std::string local_ip;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>inaddr_any <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>true</font><font face='Lucida Console'>)</font>
        <b>{</b>
            sockaddr_in local_info;
            length <font color='#5555FF'>=</font> <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>;
            <font color='#009900'>// get the local sockaddr_in structure associated with this new connection
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>getsockname</font> <font face='Lucida Console'>(</font>
                    incoming,
                    <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>local_info<font face='Lucida Console'>)</font>,
                    <font color='#5555FF'>&amp;</font>length
                <font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>
            <font face='Lucida Console'>)</font>
            <b>{</b>   <font color='#009900'>// an error occurred
</font>                <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>close</font><font face='Lucida Console'>(</font>incoming<font face='Lucida Console'>)</font>;
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                        <font color='#0000FF'>continue</font>;
                    <font color='#0000FF'>break</font>;
                <b>}</b>
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            local_ip <font color='#5555FF'>=</font> <font color='#0000FF'>const_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font> <font face='Lucida Console'>(</font>
                <font color='#BB00BB'>inet_ntop</font><font face='Lucida Console'>(</font>AF_INET,<font color='#5555FF'>&amp;</font>local_info.sin_addr,temp_local_ip,<font color='#979000'>16</font><font face='Lucida Console'>)</font>
                <font face='Lucida Console'>)</font>;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            local_ip <font color='#5555FF'>=</font> listening_ip;
        <b>}</b>



        <font color='#009900'>// set the SO_OOBINLINE option
</font>        <font color='#0000FF'><u>int</u></font> flag_value <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>setsockopt</font><font face='Lucida Console'>(</font>incoming,SOL_SOCKET,SO_OOBINLINE,<font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'>const</font> <font color='#0000FF'><u>void</u></font><font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>flag_value<font face='Lucida Console'>)</font>,<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>int</u></font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>close</font><font face='Lucida Console'>(</font>incoming<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                    <font color='#0000FF'>continue</font>;
                <font color='#0000FF'>break</font>;
            <b>}</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;  
        <b>}</b>



        <font color='#009900'>// make a new connection object for this new connection
</font>        <font color='#0000FF'>try</font> 
        <b>{</b> 
            new_connection <font color='#5555FF'>=</font> <font color='#0000FF'>new</font> <font color='#BB00BB'>connection</font> <font face='Lucida Console'>(</font>
                                    incoming,
                                    foreign_port,
                                    foreign_ip,
                                    listening_port,
                                    local_ip
                                <font face='Lucida Console'>)</font>; 
        <b>}</b>
        <font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font> 
        <b>{</b> 
            <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>close</font><font face='Lucida Console'>(</font>incoming<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                    <font color='#0000FF'>continue</font>;
                <font color='#0000FF'>break</font>;
            <b>}</b>
            <font color='#0000FF'>return</font> OTHER_ERROR; 
        <b>}</b>

        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>    <font color='#009900'>// socket creation functions
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------    
</font>
    <font color='#0000FF'>static</font> <font color='#0000FF'><u>void</u></font>
    <b><a name='close_socket'></a>close_socket</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>int</u></font> sock
    <font face='Lucida Console'>)</font>
    <font color='#009900'>/*! 
        requires
            - sock == a socket
        ensures
            - sock has been closed
    !*/</font>
    <b>{</b>
        <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> ::<font color='#BB00BB'>close</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EINTR<font face='Lucida Console'>)</font>
                <font color='#0000FF'>continue</font>;
            <font color='#0000FF'>break</font>;
        <b>}</b>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------    
</font>
    <font color='#0000FF'><u>int</u></font> <b><a name='create_listener'></a>create_listener</b> <font face='Lucida Console'>(</font>
        scoped_ptr<font color='#5555FF'>&lt;</font>listener<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> new_listener,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>short</u></font> port,
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> ip
    <font face='Lucida Console'>)</font>
    <b>{</b>
        new_listener.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        listener<font color='#5555FF'>*</font> temp;
        <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> <font color='#BB00BB'>create_listener</font><font face='Lucida Console'>(</font>temp,port,ip<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            new_listener.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>return</font> status;
    <b>}</b>

    <font color='#0000FF'><u>int</u></font> <b><a name='create_listener'></a>create_listener</b> <font face='Lucida Console'>(</font>
        listener<font color='#5555FF'>*</font><font color='#5555FF'>&amp;</font> new_listener,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>short</u></font> port,
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> ip
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#BB00BB'>sockets_startup</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;


        sockaddr_in sa;  <font color='#009900'>// local socket structure
</font>        <font color='#BB00BB'>memset</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>sa,'<font color='#FF0000'>\0</font>',<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>; <font color='#009900'>// initialize sa
</font>        

        <font color='#0000FF'><u>int</u></font> sock <font color='#5555FF'>=</font> <font color='#BB00BB'>socket</font> <font face='Lucida Console'>(</font>AF_INET, SOCK_STREAM, <font color='#979000'>0</font><font face='Lucida Console'>)</font>;  <font color='#009900'>// get a new socket
</font>
        <font color='#009900'>// if socket() returned an error then return OTHER_ERROR
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sock <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>

        <font color='#009900'>// set the local socket structure 
</font>        sa.sin_family <font color='#5555FF'>=</font> AF_INET;
        sa.sin_port <font color='#5555FF'>=</font> <font color='#BB00BB'>htons</font><font face='Lucida Console'>(</font>port<font face='Lucida Console'>)</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>ip.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>            
            <font color='#009900'>// if the listener should listen on any IP
</font>            sa.sin_addr.s_addr <font color='#5555FF'>=</font> <font color='#BB00BB'>htons</font><font face='Lucida Console'>(</font>INADDR_ANY<font face='Lucida Console'>)</font>;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            <font color='#009900'>// if there is a specific ip to listen on
</font>            sa.sin_addr.s_addr <font color='#5555FF'>=</font> <font color='#BB00BB'>inet_addr</font><font face='Lucida Console'>(</font>ip.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            <font color='#009900'>// if inet_addr couldn't convert the ip then return an error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> sa.sin_addr.s_addr <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font> in_addr_t<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font><font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
        <b>}</b>

        <font color='#009900'>// set the SO_REUSEADDR option
</font>        <font color='#0000FF'><u>int</u></font> flag_value <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>setsockopt</font><font face='Lucida Console'>(</font>sock,SOL_SOCKET,SO_REUSEADDR,<font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'>const</font> <font color='#0000FF'><u>void</u></font><font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>flag_value<font face='Lucida Console'>)</font>,<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>int</u></font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>


        <font color='#009900'>// bind the new socket to the requested port and ip
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>bind</font><font face='Lucida Console'>(</font>sock,<font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>sa<font face='Lucida Console'>)</font>,<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>   <font color='#009900'>// if there was an error 
</font>            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>; 

            <font color='#009900'>// if the port is already bound then return PORTINUSE
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EADDRINUSE<font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> PORTINUSE;
            <font color='#0000FF'>else</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;            
        <b>}</b>


        <font color='#009900'>// tell the new socket to listen
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>listen</font><font face='Lucida Console'>(</font>sock,SOMAXCONN<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// if there was an error return OTHER_ERROR
</font>            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>; 

            <font color='#009900'>// if the port is already bound then return PORTINUSE
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EADDRINUSE<font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> PORTINUSE;
            <font color='#0000FF'>else</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;   
        <b>}</b>

        <font color='#009900'>// determine the used local port if necessary
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>port <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
        <b>{</b>
            sockaddr_in local_info;
            dsocklen_t length <font color='#5555FF'>=</font> <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>getsockname</font><font face='Lucida Console'>(</font>
                sock,
                <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>local_info<font face='Lucida Console'>)</font>,
                <font color='#5555FF'>&amp;</font>length
                <font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            port <font color='#5555FF'>=</font> <font color='#BB00BB'>ntohs</font><font face='Lucida Console'>(</font>local_info.sin_port<font face='Lucida Console'>)</font>;            
        <b>}</b>

        <font color='#009900'>// initialize a listener object on the heap with the new socket
</font>        <font color='#0000FF'>try</font> <b>{</b> new_listener <font color='#5555FF'>=</font> <font color='#0000FF'>new</font> <font color='#BB00BB'>listener</font><font face='Lucida Console'>(</font>sock,port,ip<font face='Lucida Console'>)</font>; <b>}</b>
        <font color='#0000FF'>catch</font><font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font> <b>{</b> <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>; <font color='#0000FF'>return</font> OTHER_ERROR; <b>}</b>

        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'><u>int</u></font> <b><a name='create_connection'></a>create_connection</b> <font face='Lucida Console'>(</font>
        scoped_ptr<font color='#5555FF'>&lt;</font>connection<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> new_connection,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>short</u></font> foreign_port, 
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> foreign_ip, 
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>short</u></font> local_port,
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> local_ip
    <font face='Lucida Console'>)</font>
    <b>{</b>
        new_connection.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        connection<font color='#5555FF'>*</font> temp;
        <font color='#0000FF'><u>int</u></font> status <font color='#5555FF'>=</font> <font color='#BB00BB'>create_connection</font><font face='Lucida Console'>(</font>temp,foreign_port, foreign_ip, local_port, local_ip<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>status <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            new_connection.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>return</font> status;
    <b>}</b>

    <font color='#0000FF'><u>int</u></font> 
    <b><a name='create_connection'></a>create_connection</b> <font face='Lucida Console'>(</font> 
        connection<font color='#5555FF'>*</font><font color='#5555FF'>&amp;</font> new_connection,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>short</u></font> foreign_port, 
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> foreign_ip, 
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>short</u></font> local_port,
        <font color='#0000FF'>const</font> std::string<font color='#5555FF'>&amp;</font> local_ip
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#BB00BB'>sockets_startup</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        
        sockaddr_in local_sa;  <font color='#009900'>// local socket structure
</font>        sockaddr_in foreign_sa;  <font color='#009900'>// foreign socket structure
</font>        <font color='#BB00BB'>memset</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>local_sa,'<font color='#FF0000'>\0</font>',<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>; <font color='#009900'>// initialize local_sa
</font>        <font color='#BB00BB'>memset</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>foreign_sa,'<font color='#FF0000'>\0</font>',<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>; <font color='#009900'>// initialize foreign_sa
</font>
        dsocklen_t length;

        <font color='#0000FF'><u>int</u></font> sock <font color='#5555FF'>=</font> <font color='#BB00BB'>socket</font> <font face='Lucida Console'>(</font>AF_INET, SOCK_STREAM, <font color='#979000'>0</font><font face='Lucida Console'>)</font>;  <font color='#009900'>// get a new socket
</font>
        <font color='#009900'>// if socket() returned an error then return OTHER_ERROR
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>sock <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font> <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>

        <font color='#009900'>// set the foreign socket structure 
</font>        foreign_sa.sin_family <font color='#5555FF'>=</font> AF_INET;
        foreign_sa.sin_port <font color='#5555FF'>=</font> <font color='#BB00BB'>htons</font><font face='Lucida Console'>(</font>foreign_port<font face='Lucida Console'>)</font>;
        foreign_sa.sin_addr.s_addr <font color='#5555FF'>=</font> <font color='#BB00BB'>inet_addr</font><font face='Lucida Console'>(</font>foreign_ip.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#009900'>// if inet_addr couldn't convert the ip then return an error
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> foreign_sa.sin_addr.s_addr <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font> in_addr_t<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font><font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>return</font> OTHER_ERROR;
        <b>}</b>


        <font color='#009900'>// set up the local socket structure
</font>        local_sa.sin_family <font color='#5555FF'>=</font> AF_INET;

        <font color='#009900'>// set the local port
</font>        local_sa.sin_port <font color='#5555FF'>=</font> <font color='#BB00BB'>htons</font><font face='Lucida Console'>(</font>local_port<font face='Lucida Console'>)</font>;

        <font color='#009900'>// set the local ip
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>local_ip.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>            
            <font color='#009900'>// if the listener should listen on any IP
</font>            local_sa.sin_addr.s_addr <font color='#5555FF'>=</font> <font color='#BB00BB'>htons</font><font face='Lucida Console'>(</font>INADDR_ANY<font face='Lucida Console'>)</font>;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            <font color='#009900'>// if there is a specific ip to listen on
</font>            local_sa.sin_addr.s_addr <font color='#5555FF'>=</font> <font color='#BB00BB'>inet_addr</font><font face='Lucida Console'>(</font>local_ip.<font color='#BB00BB'>c_str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;  

            <font color='#009900'>// if inet_addr couldn't convert the ip then return an error
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> local_sa.sin_addr.s_addr <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font> in_addr_t<font face='Lucida Console'>)</font><font face='Lucida Console'>(</font><font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
        <b>}</b>



        

        <font color='#009900'>// bind the new socket to the requested local port and local ip
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>bind</font><font face='Lucida Console'>(</font>sock,<font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>local_sa<font face='Lucida Console'>)</font>,<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>   <font color='#009900'>// if there was an error 
</font>            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>; 

            <font color='#009900'>// if the port is already bound then return PORTINUSE
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EADDRINUSE<font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> PORTINUSE;
            <font color='#0000FF'>else</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;           
        <b>}</b>

        <font color='#009900'>// connect the socket        
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>connect</font> <font face='Lucida Console'>(</font>
                sock,
                <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>foreign_sa<font face='Lucida Console'>)</font>,
                <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>
            <font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>; 
            <font color='#009900'>// if the port is already bound then return PORTINUSE
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>errno <font color='#5555FF'>=</font><font color='#5555FF'>=</font> EADDRINUSE<font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> PORTINUSE;
            <font color='#0000FF'>else</font>
                <font color='#0000FF'>return</font> OTHER_ERROR;    
        <b>}</b>


        <font color='#009900'>// determine the local port and IP and store them in used_local_ip 
</font>        <font color='#009900'>// and used_local_port
</font>        <font color='#0000FF'><u>int</u></font> used_local_port;
        <font color='#0000FF'><u>char</u></font> temp_used_local_ip[<font color='#979000'>16</font>];
        std::string used_local_ip;
        sockaddr_in local_info;

        <font color='#009900'>// determine the port
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>local_port <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
        <b>{</b>
            length <font color='#5555FF'>=</font> <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>getsockname</font><font face='Lucida Console'>(</font>
                    sock,
                    <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>local_info<font face='Lucida Console'>)</font>,
                    <font color='#5555FF'>&amp;</font>length
                <font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>return</font> OTHER_ERROR;
            <b>}</b>
            used_local_port <font color='#5555FF'>=</font> <font color='#BB00BB'>ntohs</font><font face='Lucida Console'>(</font>local_info.sin_port<font face='Lucida Console'>)</font>;            
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            used_local_port <font color='#5555FF'>=</font> local_port;
        <b>}</b>

        <font color='#009900'>// determine the ip
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>local_ip.<font color='#BB00BB'>empty</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// if local_port is not 0 then we must fill the local_info structure
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>local_port <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                length <font color='#5555FF'>=</font> <font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font>sockaddr_in<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#BB00BB'>getsockname</font> <font face='Lucida Console'>(</font>
                        sock,
                        <font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font>sockaddr<font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>local_info<font face='Lucida Console'>)</font>,
                        <font color='#5555FF'>&amp;</font>length
                    <font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>
                <font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
                    <font color='#0000FF'>return</font> OTHER_ERROR;
                <b>}</b>
            <b>}</b>
            used_local_ip <font color='#5555FF'>=</font> <font color='#BB00BB'>inet_ntop</font><font face='Lucida Console'>(</font>AF_INET,<font color='#5555FF'>&amp;</font>local_info.sin_addr,temp_used_local_ip,<font color='#979000'>16</font><font face='Lucida Console'>)</font>;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            used_local_ip <font color='#5555FF'>=</font> local_ip;
        <b>}</b>


        <font color='#009900'>// set the SO_OOBINLINE option
</font>        <font color='#0000FF'><u>int</u></font> flag_value <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>setsockopt</font><font face='Lucida Console'>(</font>sock,SOL_SOCKET,SO_OOBINLINE,<font color='#0000FF'>reinterpret_cast</font><font color='#5555FF'>&lt;</font><font color='#0000FF'>const</font> <font color='#0000FF'><u>void</u></font><font color='#5555FF'>*</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>flag_value<font face='Lucida Console'>)</font>,<font color='#0000FF'>sizeof</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>int</u></font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>return</font> OTHER_ERROR;  
        <b>}</b>


        <font color='#009900'>// initialize a connection object on the heap with the new socket
</font>        <font color='#0000FF'>try</font> 
        <b>{</b> 
            new_connection <font color='#5555FF'>=</font> <font color='#0000FF'>new</font> <font color='#BB00BB'>connection</font> <font face='Lucida Console'>(</font>
                                    sock,
                                    foreign_port,
                                    foreign_ip,
                                    used_local_port,
                                    used_local_ip
                                <font face='Lucida Console'>)</font>; 
        <b>}</b>
        <font color='#0000FF'>catch</font><font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font> <b>{</b><font color='#BB00BB'>close_socket</font><font face='Lucida Console'>(</font>sock<font face='Lucida Console'>)</font>;  <font color='#0000FF'>return</font> OTHER_ERROR; <b>}</b>

        <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<b>}</b>

<font color='#0000FF'>#endif</font> <font color='#009900'>// POSIX
</font>
<font color='#0000FF'>#endif</font> <font color='#009900'>// DLIB_SOCKETS_KERNEL_2_CPp_
</font>

</pre></body></html>